package com.ljm.sys.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.ljm.common.enums.DataStatus;
import com.ljm.common.page.PageDto;
import com.ljm.security.util.UserUtil;
import com.ljm.service.BaseServiceImpl;
import com.ljm.sys.auth.entity.SysAuthResource;
import com.ljm.sys.auth.mapper.SysAuthResourceMapper;
import com.ljm.sys.auth.service.ISysAuthResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljm.sys.auth.api.SysAuthResourceApi;
import com.ljm.sys.auth.dto.SysAuthResourceDto;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
    * 系统权限 服务实现类
    * </p>
 *
 * @author HuamingChen
 * @since 2020-06-11
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysAuthResourceServiceImpl extends BaseServiceImpl<SysAuthResourceMapper, SysAuthResource>
        implements ISysAuthResourceService, SysAuthResourceApi {

    @Override
    public void saveData(SysAuthResourceDto dto) {
        SysAuthResource po=new SysAuthResource();
        mapperFacade.map(dto,po);
        //处理全路径
        if(dto.getParentId()==0){
            po.setResFullPath(po.getResPath());
            po.setPermissionFullCode(po.getPermissionCode());
        }else{
            SysAuthResource parent = this.getById(po.getParentId());
            if(parent!=null){
                po.setResFullPath(parent.getResFullPath()+po.getResPath());
                po.setPermissionFullCode(parent.getPermissionFullCode()+"->"+po.getPermissionCode());
            }
        }
        if(dto.getId()==null){
            po.setCreater(UserUtil.getLoginName());
            po.setCreateTime(LocalDateTime.now());
            po.setStatus(DataStatus.NORMAL.getCode());
            po.setIsDelete(false);
            po.setOrgId(UserUtil.getCurUser().getOrgId());
            this.save(po);
        }else{
            po.setEditor(UserUtil.getLoginName());
            po.setEditTime(LocalDateTime.now());
            this.updateById(po);
        }
    }

    @Override
    public void delData(Long id) {
        this.removeById(id);
    }

    @Override
    public SysAuthResourceDto getDataById(Long id) {
        SysAuthResource po = this.getById(id);
        if(po!=null){
            SysAuthResourceDto dto=new SysAuthResourceDto();
            mapperFacade.map(po,dto);
            return dto;
        }else{
            return null;
        }
    }

    @Override
    public PageDto<SysAuthResourceDto> getDataByPage(SysAuthResourceDto dto) {
        IPage<SysAuthResource> page=new Page<>(dto.getPageNo(),dto.getPageSize());
        LambdaQueryWrapper<SysAuthResource> wrapper=new LambdaQueryWrapper<>();
        if(StringUtils.isNotEmpty(dto.getResName())){
            wrapper.like(SysAuthResource::getResName,dto.getResName());
        }
        if(StringUtils.isNotEmpty(dto.getPermissionCode())){
            wrapper.like(SysAuthResource::getPermissionCode,dto.getPermissionCode());
        }
        if(StringUtils.isNotEmpty(dto.getResPath())){
            wrapper.like(SysAuthResource::getResFullPath,dto.getResPath());
        }
        if(StringUtils.isNotEmpty(dto.getResFullPath())){
            wrapper.like(SysAuthResource::getResFullPath,dto.getResFullPath());
        }
        wrapper.eq(SysAuthResource::getParentId,0L);
        page=this.page(page,wrapper);
        PageDto<SysAuthResourceDto> pageDto=new PageDto<>(dto.getPageNo(),dto.getPageSize());
        if(page.getTotal()>0){
            pageDto.setTotal(page.getTotal());
            pageDto.setRecords(mapperFacade.mapAsList(page.getRecords(),SysAuthResourceDto.class));
        }
        return pageDto;
    }

    @Override
    public List<SysAuthResourceDto> getAllRes() {
        List<SysAuthResource> list = this.list(new LambdaQueryWrapper<SysAuthResource>());
        if(CollectionUtils.isNotEmpty(list)){
            return mapperFacade.mapAsList(list,SysAuthResourceDto.class);
        }else{
            return Collections.emptyList();
        }
    }

    @Override
    public List<SysAuthResourceDto> getChlildRes(Long parentId) {
        List<SysAuthResource> list = this.list(new LambdaQueryWrapper<SysAuthResource>().eq(SysAuthResource::getParentId, parentId));
        if(CollectionUtils.isEmpty(list)){
            return Collections.emptyList();
        }else{
            return mapperFacade.mapAsList(list,SysAuthResourceDto.class);
        }
    }

    @Override
    public List<List<SysAuthResourceDto>> getResTree() {
        List<SysAuthResource> list = this.list(new LambdaQueryWrapper<SysAuthResource>());
        if(CollectionUtils.isNotEmpty(list)){
            Map<Long, List<SysAuthResource>> collect = list.stream().collect(Collectors.groupingBy(SysAuthResource::getParentId));
            List<SysAuthResourceDto> listDto=mapperFacade.mapAsList(collect.get(0L),SysAuthResourceDto.class);
            getChild(listDto,collect);
            return  Lists.partition(listDto,4);
        }else{
            return Collections.emptyList();
        }
    }

    private void getChild(List<SysAuthResourceDto> target,Map<Long, List<SysAuthResource>> source){
        if(CollectionUtils.isNotEmpty(target)){
            target.forEach(targetTemp->{
                List<SysAuthResource> children = source.get(targetTemp.getId());
                if(CollectionUtils.isNotEmpty(children)){
                    List<SysAuthResourceDto> childrenDto = mapperFacade.mapAsList(children, SysAuthResourceDto.class);
                    targetTemp.setChildren(childrenDto);
                    getChild(childrenDto,source);
                }
            });
        }
    }

    @Override
    public Map<Class, Class> classMap() {
        Map<Class, Class> map=new HashMap<>();
        map.put(SysAuthResource.class,SysAuthResourceDto.class);
        return map;
    }
}
